import os
import time

from fastapi import APIRouter, Depends, File, Form, Request, UploadFile
from starlette.responses import HTMLResponse
from tortoise.transactions import atomic

from applications import settings
from applications.common.render_template import templates
from applications.common.user_manager import permission_depends
from applications.utils.http import fail_api, success_api, table_api, PageResponse, ResultResponse
from applications.utils.upload_file.file_factory import FileUploadFactory
from applications.utils.upload_file.file_utils import FileUtils
from applications.core.exceptions import BaseAppException
from applications.models import Photo
from applications.models.admin_photo import PhotoSchema

route = APIRouter(prefix="/file", tags=["系统管理-图片管理"])


def extract_relative_path_from_url(url_path: str) -> str:
    """
    从URL路径中提取相对路径，用于文件操作

    Args:
        url_path: URL路径，如 /static/photos/test.jpg 或 photos/test.jpg

    Returns:
        str: 相对于静态文件目录的路径，如 photos/test.jpg
    """
    static_url_prefix = settings.STATIC_URL_PATH
    if url_path.startswith(static_url_prefix):
        # 如果是完整的URL路径（如 /static/photos/test.jpg），提取出相对路径
        return url_path[len(static_url_prefix) :].lstrip("/")
    elif url_path.startswith("/"):
        # 如果是其他绝对路径，去掉开头的斜杠
        return url_path.lstrip("/")
    else:
        # 如果已经是相对路径
        return url_path


#  图片管理
@route.get(
    "/",
    dependencies=[Depends(permission_depends("system:file:main"))],
    response_class=HTMLResponse,
    include_in_schema=False,
)
async def index(request: Request):
    return templates.TemplateResponse("system/photo/photo.html", {"request": request})


#  图片数据
@route.get(
    "/table",
    dependencies=[Depends(permission_depends("system:file:main"))],
    summary="获取图片数据",
    response_model=PageResponse[PhotoSchema],
)
async def table(page: int = 1, limit: int = 10):
    photos = await Photo.all().order_by("-create_time").offset((page - 1) * limit).limit(limit)
    count = await Photo.all().count()

    return table_api(data=photos, count=count)


#   上传
@route.get(
    "/upload",
    dependencies=[Depends(permission_depends("system:file:add"))],
    response_class=HTMLResponse,
    include_in_schema=False,
)
async def upload(request: Request):
    return templates.TemplateResponse("system/photo/photo_add.html", {"request": request})


#   高级上传页面
@route.get(
    "/upload-advanced",
    dependencies=[Depends(permission_depends("system:file:add"))],
    response_class=HTMLResponse,
    include_in_schema=False,
)
async def upload_advanced_page(request: Request):
    return templates.TemplateResponse("system/photo/photo_add_advanced.html", {"request": request})


#   上传接口 - 使用新的文件上传模块
@route.post(
    "/upload",
    name="system.adminFile.upload_api",
    dependencies=[Depends(permission_depends("system:file:add"))],
    summary="上传图片",
    response_model=ResultResponse,
)
async def upload_api(file: UploadFile = File(...)):
    """
    使用新的文件上传模块上传图片
    支持文件类型验证、自动缩略图生成等功能
    """
    try:
        # 使用新的文件上传模块进行上传
        result = await FileUploadFactory.upload_with_result(
            path="photos",  # 图片专用目录
            file=file,
            upload_type="local",  # 使用本地存储
            file_type="image",  # 指定为图片类型
            max_size=10,  # 最大10MB
            create_thumbnail=True,  # 自动创建缩略图
        )

        if not result.success:
            return fail_api(msg=result.error or "上传失败")

        # 获取文件信息
        file_info = result.file_info or {}
        file_size = file_info.get("size", 0)

        # 生成数据库记录用的文件名
        filename = os.path.basename(result.file_path) if result.file_path else file.filename or "unknown"

        # 保存到数据库
        photo = Photo(
            name=filename,
            href=result.url,  # 使用新模块返回的URL
            mime=file.content_type or "image/jpeg",
            size=str(file_size),
        )
        await photo.save()

        # 返回成功响应，包含更多信息
        response_data = {
            "src": photo.href,
            "file_info": {
                "id": photo.id,
                "name": photo.name,
                "size": photo.size,
                "mime": photo.mime,
                "thumbnail_url": result.thumbnail_path,  # 缩略图URL
            },
        }

        return success_api(msg="图片上传成功", data=response_data)

    except BaseAppException as e:
        return fail_api(msg=str(e))
    except Exception as e:
        return fail_api(msg=f"上传失败: {str(e)}")


#    图片删除 - 使用新的文件上传模块
@route.post(
    "/delete",
    dependencies=[Depends(permission_depends("system:file:delete"))],
    summary="删除图片",
    response_model=ResultResponse,
)
async def delete(id: int = Form(...)):
    """
    删除图片，使用新的文件上传模块进行文件删除
    """
    photo = await Photo.get_or_none(id=id)
    if not photo:
        return fail_api(msg="图片不存在")

    try:
        # 尝试使用新的文件上传模块删除文件
        relative_path = extract_relative_path_from_url(photo.href)

        # 使用工厂类删除文件
        delete_success = await FileUploadFactory.delete_file(file_path=relative_path, upload_type="local")

        # 无论文件删除是否成功，都删除数据库记录
        # 因为可能文件已经被手动删除了
        await photo.delete()

        if delete_success:
            return success_api(msg="图片删除成功")
        else:
            return success_api(msg="图片记录已删除（文件可能已不存在）")

    except Exception as e:
        # 如果新模块失败，回退到原始删除方法
        try:
            # 构造旧的文件路径
            file_path = os.path.join(settings.UPLOADED_PHOTOS_DEST, photo.name)
            if os.path.exists(file_path):
                os.remove(file_path)
        except Exception:
            pass  # 忽略文件删除错误

        # 删除数据库记录
        await photo.delete()
        return success_api(msg="图片删除成功")


# 图片批量删除 - 使用新的文件上传模块
@route.post(
    "/batchRemove",
    name="system.adminFile.batch_remove",
    dependencies=[Depends(permission_depends("system:file:delete"))],
    summary="批量删除图片",
    response_model=ResultResponse,
)
@atomic()
async def batch_remove(ids: list[int] = Form(...)):
    """
    批量删除图片，使用新的文件上传模块
    """
    photos = await Photo.filter(id__in=ids).all()

    if not photos:
        return fail_api(msg="没有找到要删除的图片")

    success_count = 0
    total_count = len(photos)

    # 删除文件
    for photo in photos:
        try:
            # 从URL路径中提取相对路径
            relative_path = extract_relative_path_from_url(photo.href)

            # 使用新的文件上传模块删除文件
            delete_success = await FileUploadFactory.delete_file(file_path=relative_path, upload_type="local")

            if delete_success:
                success_count += 1
        except Exception as e:
            # 如果新模块失败，尝试使用旧方法
            try:
                file_path = os.path.join(settings.UPLOADED_PHOTOS_DEST, photo.name)
                if os.path.exists(file_path):
                    os.remove(file_path)
                    success_count += 1
            except Exception:
                pass  # 忽略单个文件删除错误

    # 删除数据库记录
    deleted_count = await Photo.filter(id__in=ids).delete()

    message = f"批量删除完成：数据库记录删除 {deleted_count} 条，文件删除 {success_count} 个"
    return success_api(msg=message)


# 高级文件上传接口 - 支持更多选项
@route.post(
    "/upload-advanced",
    name="system.adminFile.upload_advanced",
    dependencies=[Depends(permission_depends("system:file:add"))],
    summary="高级图片上传",
    response_model=ResultResponse,
)
async def upload_advanced(
    file: UploadFile = File(...),
    upload_type: str = Form("local", description="上传类型: local, qiniu"),
    create_thumbnail: bool = Form(True, description="是否创建缩略图"),
    compress_image: bool = Form(True, description="是否压缩图片"),
    max_size: int = Form(10, description="最大文件大小(MB)"),
):
    """
    高级图片上传接口，支持更多自定义选项
    - 支持选择上传类型（本地/七牛云）
    - 支持自动缩略图生成
    - 支持图片压缩
    - 支持自定义文件大小限制
    """
    try:
        # 验证上传类型
        if not FileUploadFactory.validate_upload_type(upload_type):
            return fail_api(msg=f"不支持的上传类型: {upload_type}")

        # 使用新的文件上传模块
        result = await FileUploadFactory.upload_with_result(
            path="photos",
            file=file,
            upload_type=upload_type,
            file_type="image",
            max_size=max_size,
            create_thumbnail=create_thumbnail,
        )

        if not result.success:
            return fail_api(msg=result.error or "上传失败")

        # 如果需要压缩图片
        if compress_image and result.file_path:
            try:
                FileUtils.compress_image(result.file_path, quality=85, max_width=1920, max_height=1080)
            except Exception as e:
                # 压缩失败不影响上传结果
                pass

        # 获取文件信息
        file_info = result.file_info or {}
        file_size = file_info.get("size", 0)
        filename = os.path.basename(result.file_path) if result.file_path else file.filename or "unknown"

        # 保存到数据库
        photo = Photo(name=filename, href=result.url, mime=file.content_type or "image/jpeg", size=str(file_size))
        await photo.save()

        # 构造响应数据
        response_data = {
            "src": photo.href,
            "file_info": {
                "id": photo.id,
                "name": photo.name,
                "size": photo.size,
                "mime": photo.mime,
                "upload_type": upload_type,
                "thumbnail_url": result.thumbnail_path,
                "compressed": compress_image,
            },
        }

        return success_api(msg="高级上传成功", data=response_data)

    except BaseAppException as e:
        return fail_api(msg=str(e))
    except Exception as e:
        return fail_api(msg=f"高级上传失败: {str(e)}")


# 获取文件信息接口
@route.get(
    "/info/{photo_id}",
    dependencies=[Depends(permission_depends("system:file:main"))],
    summary="获取图片详细信息",
    response_model=ResultResponse,
)
async def get_photo_info(photo_id: int):
    """
    获取图片的详细信息，包括文件系统信息
    """
    photo = await Photo.get_or_none(id=photo_id)
    if not photo:
        return fail_api(msg="图片不存在")

    try:
        # 从URL路径中提取相对路径
        relative_path = extract_relative_path_from_url(photo.href)

        # 使用新模块检查文件是否存在
        file_exists = await FileUploadFactory.file_exists(file_path=relative_path, upload_type="local")

        if file_exists:
            # 获取详细文件信息
            file_info = await FileUploadFactory.get_file_info(file_path=relative_path, upload_type="local")
        else:
            file_info = {"error": "文件不存在"}

        response_data = {
            "photo": {
                "id": photo.id,
                "name": photo.name,
                "href": photo.href,
                "mime": photo.mime,
                "size": photo.size,
                "create_time": photo.create_time,
            },
            "file_exists": file_exists,
            "file_info": file_info,
        }

        return success_api(msg="获取信息成功", data=response_data)

    except Exception as e:
        return fail_api(msg=f"获取信息失败: {str(e)}")
